"""
 from threading import thread 的并发网络
 
 流程:
    创建套接字
    循环接收客户端连接请求
    当有新的客户端连接,创建线程处理客户端请求
    主线程继续等待其他客户端连接请求
    当客户端退出,则对应的分支线程退出
"""
from threading import Thread  # 多线程
from socket import *  # 网络
import sys

ADDR = ('0.0.0.0', 18693)


class MyProcess:
    def __init__(self):
        # 线程没有僵尸线程一说,所以这里不需要
        # signal.signal(signal.SIGCHLD, signal.SIG_IGN)
        self.__sockfd = socket()
        self.__sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 端口复用
        self.__sockfd.bind(ADDR)
        self.__sockfd.listen(5)
        self.__lie = [self.__handle, self.__fun1]
        self.__lie_ = []

    def main(self):
        while True:
            print("等待链接中...")
            try:
                connfd, addr = self.__sockfd.accept()  # 阻塞等待
                print(f"有客户端连接: {addr}")
            except KeyboardInterrupt:
                print("检测到客户端非正常退出!")
                sys.exit()
            except Exception as e:
                print(f"遇到了错误: {e}")
                continue

            self.zi_socket(connfd, addr)

    # 创建子进程
    def zi_socket(self, *args):
        for i in self.__lie:
            so = Thread(target=i, args=args)  # 实例化
            so.daemon = True  # 主线程推则全退
            so.start()  # 开始
            self.__lie_.append(so)  # 追加

        [so.join() for i in self.__lie_]  # 回收

    # 子进程
    def __handle(self, *args):  # 如果有多个子进程同时执行, 传参必须一样,否则报错
        """
        子进程
        """
        c = args[0]
        d = args[1]
        while True:
            data = c.recv(1024)  # 收取消息
            if not data:
                break
            print(f"客户端: {d}发送的消息: {data.decode()}")
            c.send('ok'.encode())
        c.close()

    # 子进程1
    def __fun1(self, *args):
        print(f"这是第二个进程.{args[0], {args[1]}}")


so = MyProcess()
so.main()
